-- UIActivityExchange
-- Create by chendh
-- 活动兑换

-- UIActivityExchange继承自Layer
UIActivityExchange = class("UIActivityExchange", function()
    return cc.Layer:create();
end);

function UIActivityExchange.create(activityId)
    return UIActivityExchange.new(activityId);
end

-- 商品格最大行数和列数
local MAX_GRID_ROW    = 2;
local MAX_GRID_COLUMN = 4;

-- 商品类型
local HERO  = 3;
local TREASURE = 6;
local ROBOT = 8;

-- 内部函数声明

-- 构造函数
function UIActivityExchange:ctor(activityId)
    -- 初始化
    self:setName("UIActivityExchange");
    local node = cc.CSLoader:createNode("layout/shop/BlackMarket.csb");
    self:addChild(node);
    self.node = node;

    self.activityId = activityId;

    local CT = node:getChildByName("CT");
    local scrollview = CT:getChildByName("scroll_view");
    self.CT = CT;
    self.scrollView = scrollview;
    self.scrollView:setVisible(true);

    -- 水平滑动，需要显示左右蒙版
    local mask3 = findChildByName(self.node, "CT/mask3");
    mask3:setVisible(true);
    local mask4 = findChildByName(self.node, "CT/mask4");
    mask4:setVisible(true);

    local activityInfo = ActivityM.query(activityId, "activity_items");
    if type(activityInfo) == "table" and #activityInfo > 0 then
        self.currency = activityInfo[1];
    end

    -- 修改滚动方向
    -- 1 垂直
    -- 2 水平
    self.scrollView:setDirection(2);

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 初始化商品格子
    self:initGoodsGrids(self.node);

    -- 重绘
    self:redraw();

    self:checkBtn();

    -- 适配
    self:resize();
end

-- 适配
function UIActivityExchange:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 初始化商品格
function UIActivityExchange:initGoodsGrids(node)
    local w = DESIGN_WIDTH;
    local h = DESIGN_HEIGHT;

    -- 图标间距(横向)
    local wGap = 23;

    -- 图标间距(纵向)
    local hGap = 33;

    -- 图标宽度
    local iconWidth = 128;

    -- 图片高度
    local iconHeight = 163;

    local topHGap  = 100;
    local leftWGap = 20;

    -- 收集商品信息
    local goodsList = self:gatherGoodsInfo();

    -- 商品的共个数
    local shopCount = #goodsList;

    self.scrollView.rows = {};
    self.scrollView:removeAllChildren();

    local itemNode = cc.CSLoader:createNode("layout/shop/BlackMarketGoodsIcon.csb");
    -- @param windowNode    界面节点
    -- @param scrollNode    容器节点
    -- @param itemNode      单元格的节点
    -- @param totalNum      单元格总数
    -- @param maxRowNum     最大行数
    -- @param pageColNum    单页可以显示下的列数
    -- @param wGap          单元格间距(横向) 这里作为最小值使用
    -- @param hGap          单元格间距(纵向)
    -- @param iconWidth     单元格宽度
    -- @param iconHeight    单元格高度
    -- @param topHGap       上方留
    -- @param leftWGap      左右留白  这里作为最小值使用
    -- @param touchEvent    点击事件注册函数
    initScrollGridsHorizontal(self, self.scrollView, itemNode, shopCount, MAX_GRID_ROW, MAX_GRID_COLUMN, wGap, hGap, iconWidth, iconHeight, topHGap, leftWGap, self.registerItemTouchEvent);
end

-- 清空所有的商品格
function UIActivityExchange:clearAllGrid()
    -- 格子总数
    local totalGridCount = MAX_GRID_ROW * MAX_GRID_COLUMN;
    for i = 1, totalGridCount do
        local grid = self.scrollView:getChildByName("item" .. i);
        if grid then
            grid:setVisible(false);
        end
    end
end

-- 显示商店
function UIActivityExchange:redraw()
    -- 显示标题
    local titleLabel = findChildByName(self.CT, "title");
    TextStyleM.setTitleStyle(titleLabel);

    if self:isSkyActivity() then
        titleLabel:setString(getLocStr("sky_activity_exchange_title"));
    else
        local title = ActivityM.query(self.activityId, "exchange_title");
        titleLabel:setString(title);
    end

    -- 绘制倒计时
    self:redrawTime();

    -- 收集商品信息
    local goodsList = self:gatherGoodsInfo();
    local totalGridCount = #goodsList;

    if not goodsList or #goodsList == 0 then
        cclog("收集商品信息失败。");
        self:clearAllGrid();
        return;
    end

    -- 显示商品信息
    local totalGoodsCount = #goodsList;
    for i = 1, totalGridCount do
        local grid          = self.scrollView:getChildByName("item" .. i);
        local goodsBg       = grid:getChildByName("bg");
        local iconImg       = grid:getChildByName("goods_icon");
        local moneyImg      = grid:getChildByName("money_icon");
        local moneyLabel    = grid:getChildByName("money_count");
        local soldOutLabel  = grid:getChildByName("sold_out");
        local rankNode      = grid:getChildByName("star_node");
        local countLabel    = grid:getChildByName("item_count");

        if i <= totalGoodsCount then
            grid:setVisible(true);

            local goodsIndex = goodsList[i][1]    -- 商品序号
            local goodsId    = goodsList[i][2];   -- 商品id
            local goodsIcon  = goodsList[i][3];   -- 商品图标
            local payType    = goodsList[i][4];   -- 支付类别
            local payAttrib  = goodsList[i][5];   -- 支付属性
            local goodsPrice = goodsList[i][6];   -- 商品价格
            local goodsCount = goodsList[i][7];   -- 商品数量
            local count      = goodsList[i][8];   -- 剩余兑换次数
            local itemName   = goodsList[i][9];   -- 物品名称
            local itemDesc   = goodsList[i][10];  -- 物品描述
            local soldOut    = goodsList[i][11];  -- 是否售完
            local rank       = goodsList[i][12];  -- 阶位
            local classify   = goodsList[i][13];  -- 商品类型
            local extra      = goodsList[i][14];  -- 附加信息

            -- 为商品图标绑定信息
            iconImg.goodsIndex = goodsIndex;
            iconImg.goodsId    = goodsId;
            iconImg.goodsIcon  = goodsIcon;
            iconImg.payType    = payType;
            iconImg.payAttrib  = payAttrib;
            iconImg.goodsPrice = goodsPrice;
            iconImg.goodsCount = goodsCount;
            iconImg.count      = count;
            iconImg.itemName   = itemName;
            iconImg.itemDesc   = itemDesc;
            iconImg.soldOut    = soldOut;
            iconImg.rank       = rank;
            iconImg.extra      = extra;
            iconImg.classify   = classify;

            if not self.currency then
                self.currency = payAttrib;
            end

            -- 显示商品名称和数量
            TextStyleM.setTextStyle(countLabel, TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, -2);
            if goodsCount >= 1 then
                -- 需要显示数量
                countLabel:setString(tostring(goodsCount));
            else
                countLabel:setVisible(false);
            end

            -- 显示商品图标
            if classify == TREASURE then
                iconImg:loadTexture(getAirShipSkillIconPath(goodsIcon));
            elseif classify == ROBOT then
                iconImg:loadTexture(getRobotIconPath(goodsIcon));
            elseif classify == HERO then
                iconImg:loadTexture(getMiddleHeroIconPath(goodsIcon));
            elseif type(goodsIcon) == "string" then
                iconImg:loadTexture(getLargeAttribIconPath(goodsIcon));
                iconImg:setScale(1.2);
            else
                iconImg:loadTexture(getItemIconPath(goodsIcon));
            end

            -- 显示价格
            local offset = 0;
            local iconPath;

            -- 属性支付
            if 2 == payType then
                iconPath = getSmallAttribIconPath(FieldsM.query(payAttrib, "icon"));
                moneyImg:loadTexture(iconPath);
                moneyImg:setScale(0.83);
                offset = 5;
            elseif 1 == payType then
                -- 物品支付
                iconPath = getItemIconPath(ItemM.query(payAttrib, "icon"));
                moneyImg:setScale(0.45);
                moneyImg:loadTexture(iconPath);
            end

            TextStyleM.setTextStyle(moneyLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_WHITE, true);
            moneyLabel:setString(tostring(goodsPrice));
            moneyLabel:getVirtualRenderer():setAdditionalKerning(getLocKerning() -3);

            if 2 == payType then
                local activityData = SkyActivityM.getActivityData(self.activityId);
                local ownAmount;
                if ActivityM.query(self.activityId, "type") == ACTIVITY_TYPE_DUNGEON then
                    ownAmount = ME.user:queryAttrib(payAttrib);
                else
                    local medalClassId  = SkyActivityM.query(self.activityId, "medal_class_id");
                    ownAmount = ItemM.getAmount(ME.user, medalClassId);
                end

                if ownAmount < goodsPrice then
                    moneyLabel:setTextColor(TextStyleM.TEXT_COLOR_LIGHT_RED);
                else
                    moneyLabel:setTextColor(TextStyleM.TEXT_COLOR_WHITE);
                end
            else
                if ItemM.getAmount(ME.user, payAttrib) < goodsPrice then
                    moneyLabel:setTextColor(TextStyleM.TEXT_COLOR_LIGHT_RED);
                else
                    moneyLabel:setTextColor(TextStyleM.TEXT_COLOR_WHITE);
                end
            end

            -- 居中显示
            local moneyImgW = moneyImg:getContentSize().width * moneyImg:getScaleX();
            local moneyLabelW = moneyLabel:getContentSize().width;
            -- 间隔
            local gap = 5;
            local s = (moneyImgW + moneyLabelW + gap) / 2;
            -- 位置调整
            moneyImg:setPositionX(-s - offset / 2 );
            moneyLabel:setPositionX(moneyImg:getPositionX() + offset + moneyImgW + gap);

            -- 如果商品已售完，显示图标
            if soldOut then
                -- 背景变灰
                setGrayTransMode(goodsBg, true);
                setGrayTransMode(iconImg, true);

                -- 不显示价格、星星
                moneyImg:setVisible(false);
                moneyLabel:setVisible(false);
                rankNode:setVisible(false);

                -- 显示已出售字样
                soldOutLabel:setVisible(true);
                TextStyleM.setTextStyle(soldOutLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_ORANGE, true);
                soldOutLabel:getVirtualRenderer():setAdditionalKerning(getLocKerning() -3);
                soldOutLabel:setString(getLocStr("has_been_exchange"));
            else
                -- 背景变亮
                setGrayTransMode(goodsBg, false);
                setGrayTransMode(iconImg, false);

                -- 显示图标、价格、星星
                moneyImg:setVisible(true);
                moneyLabel:setVisible(true);
                rankNode:setVisible(true);

                soldOutLabel:setVisible(false);
            end
        else
            -- 清空多余的格子
            grid:setVisible(false);
        end
    end
end

-- 绘制时间
function UIActivityExchange:redrawTime()
    if self.isTick then
        return;
    end
    local function tick()
        -- 提示信息
        local leftTime = ActivityM.getRemainRunningTime(self.activityId);
        local txt1Label = findChildByName(self.CT, "subhead");

        TextStyleM.setSubheadStyle(txt1Label);
        txt1Label:setString(string.format(getLocStr("sky_activity_exchange_time"), remainingTimeDesc(leftTime)));

        performWithDelay(self, tick, 1);
    end
    self.isTick = true;
    tick();
end

-- 是否是天空活动
function UIActivityExchange:isSkyActivity()
    return ActivityM.query(self.activityId, "type") == ACTIVITY_TYPE_SKY;
end

-- 排序
local sortGoodsList = function(a, b)
    if type(a.pos) ~= "number" and type(b.pos) ~= "number" then
        return a.id < b.id;
    elseif not a.pos then
        return false;
    elseif not b.pos then
        return true;
    end

    return tonumber(a.pos) < tonumber(b.pos);
end

-- 获取可购买的商品信息
function UIActivityExchange:gatherGoodsInfo()
    local goodsId;
    local activityId = self.activityId;

    if self:isSkyActivity() then
        -- 天空活动
        goodsList = SkyActivityM.getActivityExchangeList(activityId);
    else
        -- 其他活动
        goodsList = ActivityM.getActivityExchangeList(activityId);
        table.sort(goodsList, sortGoodsList);
    end

    if goodsList == nil then
        return nil;
    end

    local ret = {};
    local goodsIndex = 1;  -- 商品的序号
    for _, info in pairs(goodsList) do
        local goodsId    = info.id;
        local price      = info.price;
        local goodsInfo  = info.bonus;
        local count      = info.count;

        local payType    = price[1];           -- 支付类型(1:道具，2:属性)
        local payAttrib  = price[2];           -- 支付属性
        local goodsPrice = price[3];           -- 商品价格
        local soldOut    = iif(info.count == 0, true, false);

        if type(goodsInfo) == "table" then
            local classId    = goodsInfo[2];
            local goodsCount = goodsInfo[3];      -- 商品数量
            local goodsType  = goodsInfo[1];

            local itemInfo;
            local iconPath;
            if goodsType == TREASURE then
                itemInfo = SkyShipSkillM.query(classId);
            elseif goodsType == ROBOT then
                itemInfo = SkyRobotM.query(classId);
            elseif goodsType == HERO then
                itemInfo = PetM.query(classId);
                iconPath = PetM.getDefaultIcon(classId);
            elseif type(classId) == "string" then
                itemInfo = FieldsM.getFieldInfo(classId);
            else
                itemInfo = ItemM.query(classId);
            end

            iconPath = iconPath or itemInfo["icon"];

            if itemInfo then
                table.insert(ret, {goodsIndex, goodsId, iconPath, payType, payAttrib, goodsPrice,
                    goodsCount, count, itemInfo["name"], itemInfo["desc"], soldOut, itemInfo["rank"], goodsType});
            end
        else
            local goodsCount = 1;
            local rank = 1;
            local goodsType = info["goods_type"];
            local icon = info["icon"];
            local desc = info["desc"];
            local name = info["name"];
            local extraDesc = info["extra_desc"];
            local extra = {
                ["name"] = name,
                ["icon"] = icon,
                ["desc"] = desc,
                ["extra_desc"] = extraDesc;
                ["goods_type"] = goods_type,
            };
            table.insert(ret, {goodsIndex, goodsId, icon, payType, payAttrib, goodsPrice,
                goodsCount, count, name, desc, soldOut, rank, goodsType, extra});
        end

        goodsIndex = goodsIndex + 1;
    end

    return ret;
end

-- 注册商品点击事件
function UIActivityExchange:registerItemTouchEvent(node)
    -- 注册商品图标点击事件
    local image = node:getChildByName("bg");
    local iconImg = node:getChildByName("goods_icon");
    local function onClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 仅处理非空的格子
            if type(iconImg.goodsIcon) == 'number' or type(iconImg.goodsIcon) == "string" then
                self:onGoodsClick(iconImg);
                AudioM.playFx("button_spell");
            end
        end
    end
    image:addTouchEventListener(onClick)
end

-- 注册事件处理回调函数
function UIActivityExchange:registerEventCallback()
    EventMgr.removeAll("UIActivityExchange");

    -- 关注触发事件
    EventMgr.register("UIActivityExchange", event.SLIME_TALK, function(args)
        self.args = args;
    end);

    -- 关注兑换活动商品的事件
    EventMgr.register("UIActivityExchange", event.ACTIVITY_EXCHANGE, function(args)
        local goodsId   = args.goodsId;
        local num       = args.num;
        local bonus     = args.bonus;

        self:whenExchange(goodsId, num, bonus);
    end);

    -- 关注活动关闭事件
    EventMgr.register("UIActivityExchange", event.ACTIVITY_CLOSE, function(args)
        -- 如果是当前活动关闭了，那么退出兑换界面
        if self.activityId == args["id"] then
            -- 关闭当前界面
            AudioM.playFx("ship_return");
            UIMgr.getCurrentScene():removeFormByName("UIActivityExchange");
        end
    end);

    -- 关注激活宠物事件
    EventMgr.register("UIActivityExchange", event.GAIN_PET, function()
        -- 检查按钮
        self:checkBtn();
    end);

    -- 注册获得焦点的回调
    EventMgr.register("UIActivityExchange", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UIActivityExchange" then
            -- 如果是天空活动
            if self:isSkyActivity() then
                -- TopMenu显示天空活动的数据和袭击次数
                local uiTopMenu = UIMgr:getCurrentScene().topMenu;
                uiTopMenu:setSkyActivityId(self.activityId);
                uiTopMenu:show(TOPMENU_FRAME_ACTIVITY_DATA, TOPMENU_FRAME_ACTIVITY_TIMES, TOPMENU_FRAME_HEAD_AIRSHIP);
            else
                -- 显示活动兑换的货币信息
                local uiTopMenu = UIMgr:getCurrentScene().topMenu;
                uiTopMenu:setExchangeCurrency(self.currency);
                uiTopMenu:show(TOPMENU_FRAME_ACTIVITY_EXCHANGE, TOPMENU_FRAME_GEM);
            end

            if para["lose"] == "UIHeroDetailInfo" then
                -- 可能有事件要触发
                self:triggerSlimeEvent();
            end
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            EventMgr.removeAll("UIActivityExchange");
        end
    end);
end

-- 注册点击事件
function UIActivityExchange:registerTouchEvent()
    -- 注册招募按钮点击事件
    local btnRecruit = findChildByName(self.node, "BT/refresh");

    local campId;
    local petList;
    if self:isSkyActivity() then
        petList = SkyActivityM.getSkyActivityRecruitList(self.activityId);
        if #petList > 0 then
            btnRecruit:setVisible(true);
        else
            btnRecruit:setVisible(false);
        end
    else
        btnRecruit:setVisible(false);
    end

    local function onRecruitClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 打开招募界面
            AudioM.playFx("ship_return");

            require "game/ui/form/shop/UIPetRecruit"
            UIMgr.getCurrentScene():removeFormByName("UIPetRecruit");
            local uiPetRecruit = UIPetRecruit.create(campId, petList);
            UIMgr.getCurrentScene():addForm(uiPetRecruit);
        end
    end
    btnRecruit:addTouchEventListener(onRecruitClick);
    TextStyleM.setTextStyle(btnRecruit, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnRecruit:setTitleText(getLocStr("btn_text_recruit"));

    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("ship_return");
            UIMgr.getCurrentScene():removeFormByName("UIActivityExchange");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));
end

-- 检查按钮
function UIActivityExchange:checkBtn()
    local btnRecruit = findChildByName(self.node, "BT/refresh");
    local hintImg = findChildByName(btnRecruit, "hint");
    -- 如果有可招募的冈布奥，需要显示气泡
    local petList = SkyActivityM.getSkyActivityRecruitList(self.activityId);
    if #petList > 0 then
        local canRecruit = false;
        for _, petId in ipairs(petList) do
            if PetShopM.canHirePet(petId) then
                canRecruit = true;
                break;
            end
        end

        if canRecruit then
            hintImg:setVisible(true);
            checkBlueBubbleStatus(hintImg, true);
        else
            hintImg:setVisible(false);
        end
    else
        hintImg:setVisible(false);
    end
end

-- 当商品被点击
function UIActivityExchange:onGoodsClick(iconImg)
    if iconImg.soldOut then
        -- 兑换数量已达上限
        alert(getLocStr("goods_exchange_over"));
        return;
    end

    local id = iconImg.goodsId;
    local multi;
    local costume;
    if self:isSkyActivity() then
        multi = SkyActivityM.queryExchange(id, "multi");
    else
        multi = ActivityM.queryExchange(id, "multi");
        local bonus = ActivityM.queryExchange(id, "bonus");
        if type(bonus) == "table" then
            if bonus[1] == 1 and ItemM.query(bonus[2], "type") == ITEM_TYPE_COSTUME then
                -- 时装
                costume = bonus[2];
            end
        end
    end

    if multi == 1 then
        -- 显示批量兑换界面
        require "game/ui/form/activity/UIActivityExchangeMulti"
        local uiMultiExchange = UIActivityExchangeMulti.create(self.activityId, id);
        UIMgr.getCurrentScene():addForm(uiMultiExchange);
    elseif iconImg.classify == HERO then
        -- 英雄兑换
        local classId = ActivityM.queryExchange(id, "bonus")[2];
        require "game/ui/form/hero/UIHeroDetailInfo";
        UIMgr.getCurrentScene():removeFormByName("UIHeroDetailInfo");
        uiGoodsDetail = UIHeroDetailInfo.create(classId, "activityShop", id);
        UIMgr.getCurrentScene():addForm(uiGoodsDetail);
    elseif type(costume) == "number" then
        -- 时装
        require "game/ui/form/hero/UIBuyCostume";
        local dbase = ItemM.query(costume, "desc_args");
        local uiform = UIBuyCostume.create(dbase["pet_id"], costume, "activity");
        UIMgr.getCurrentScene():addForm(uiform);
    else
        -- 显示商品详细信息
        require "game/ui/form/activity/UIActivityGoodsInfo"
        local uiGoodsDetail = UIActivityGoodsInfo.create(self.activityId, id, iconImg.extra);
        UIMgr.getCurrentScene():addForm(uiGoodsDetail);
    end
end

-- 关闭购买商品的消息
function UIActivityExchange:whenExchange(goodsIndex, num, bonus)
    -- 刷新界面
    self:redraw();

    -- 提示玩家兑换了商品
    local function delay()
        if bonus[1] == 1 then
            name = ItemM.query(bonus[2], "name");
        elseif bonus[1] == ROBOT then
            name = SkyRobotM.query(bonus[2], "name");
        elseif bonus[1] == 2 then
            name = FieldsM.query(bonus[2], "name");
        elseif bonus[1] == HERO then
            name = PetM.query(bonus[2], "name");
        else
            name = SkyShipSkillM.query(bonus[2], "name");
        end

        count = num * bonus[3];

        if bonus[1] == HERO then
            msg = string.format(getLocStr("exchange_pet"), name);
        else
            msg = string.format(getLocStr("exchange_tip"), name, count);
        end

        alert(msg);
    end

    performWithDelay(self, delay, 0.1);

    UIMgr.getCurrentScene():removeFormByName("UIBuyCostume");
end

-- 触发了史莱姆事件
function UIActivityExchange:triggerSlimeEvent()
    local args = self.args;
    if type(args) ~= "table"
        or SlimeEventM.query(args.eventId, "rule") ~= "spring_exchange" then
        return;
    end

    local para = args.para or {};
    local id = tonumber(para.exchange_id);
    if table.indexOf({51,52,53,54}, id) < 0 then
        -- 不是指定的兑换
        return;
    end

    local msgList = args.msgList;
    local endEffect = args.endEffect;

    require "game/ui/form/hero/UIHeroSpeak"
    local uiForm = UIHeroSpeak.create(self, args.heroId, msgList, "B_FLY_IN", "B_FLY_OUT", nil, endEffect, args);
    UIMgr.getCurrentScene():addForm(uiForm);

    -- 清除缓存参数
    self.args = nil;
end